<?php

require_once 'LogConsole.php';

/**
 * @author Lisette 
 */
class LDAPHandler {

    var $_connection;
    var $_protocol = "ldap://";
    var $_port = "389";
    var $_server = "private.cdl.uni-saarland.de";
    var $_base_dn = "dc=cdl,dc=cs,dc=uni-saarland,dc=de";
    var $_base_dc = "ou=people,dc=cdl,dc=cs,dc=uni-saarland,dc=de";
    var $_ldapuser = "uid=se2012,ou=people,dc=cdl,dc=cs,dc=uni-saarland,dc=de";
    var $_ldappassword = "T21F4wQqUn6goNY";
    var $_strconexion = "";
    var $_errorCode;
    var $_errorText;

    /**
     * LDAP connection
     * @return boolean 
     */
    private function connect() {
        $this->_connection = ldap_connect($this->_server);
        if ($this->_connection) {
            $this->handleMessage("{LDAPHandler} Connection Success");
        } else {
            $this->handleErrors("{LDAPHandler} Connection Error");
            return false;
        }
        return true;
    }

    /**
     * Any message logging
     * @param type $message 
     */
    private function handleMessage($message) {
        //logConsole('LDAPHandler message: ', $message, true);
    }

    /**
     * Errors Logging
     * @param type $message 
     */
    private function handleErrors($message) {
        $this->_errorCode = ldap_errno($this->_connection);
        $this->_errorText = ldap_error($this->_connection);
        $this->handleMessage("{LDAPHandler} " . $message . " " . $this->_errorCode . " " . $this->_errorText);
    }

    /**
     * Ldap disconnection 
     */
    private function disconnect() {
        ldap_unbind($this->_connection);
        ldap_close($this->_connection);
    }

    /**
     * LDAP binding
     * @return boolean 
     */
    private function bind() {
        ldap_set_option($this->_connection, LDAP_OPT_SIZELIMIT, 500);
        ldap_set_option($this->_connection, LDAP_OPT_PROTOCOL_VERSION, 3);
        ldap_set_option($this->_connection, LDAP_OPT_REFERRALS, 0);

        $tls = ldap_start_tls($this->_connection);

        if ($tls) {
            $bind = ldap_bind($this->_connection, $this->_ldapuser, $this->_ldappassword);

            if ($bind) {
                $this->handleMessage("{LDAPHandler} Binding Success");
            } else {
                $this->handleErrors("Connection Binding Error");
                return false;
            }
            return true;
        }
        return false;
    }

    /**
     * Retrieves an existing User
     * @param type $username
     * @return string 
     */
//    public function searchUser($username) {
//        $user = null;
//
//        if ($this->connect()) {
//            if ($this->bind()) {
//                $query = "(uid=$username*)";
//                $this->handleMessage("query: " . $query);
//                $result = $this->find($query);
//
//                if (ldap_count_entries($this->_connection, $result) == 0) {
//                    $this->handleMessage("{LDAPHandler} Search User ($username does not exists)");
//                } else {
//                    $entry = ldap_first_entry($this->_connection, $result);
//                    $user = ":)"; //here we need to create an User object based on the retrieved values
//                    $this->handleMessage("{LDAPHandler} Search User OK ($username found)");
//                }
//            }
//            $this->disconnect();
//        }
//        return $user;
//    }

    /**
     * User Authentication
     * @param type $username
     * @param type $password
     * @return boolean 
     * @author Lisette
     */
    public function authenticate($username, $password) {
        $user = null;
        ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, 7);

        if ($this->connect()) {
            if ($this->bind()) {
                $query = "(uid=$username*)";
                $result = $this->find($query);

                if (ldap_count_entries($this->_connection, $result) == 0) {
                    $this->handleMessage("{LDAPHandler} Search User ($username does not exists)");
                } else {
                    $entry = ldap_first_entry($this->_connection, $result);

                    /* AUTHENTICATION */
                    $user = $this->convertToUser($entry);
                    if ($user->getUsername() != $username) {
                        $this->disconnect();
                    }

                    $entryDN = "uid=" . $user->getUsername() . "," . $this->_base_dc;
                    $ru = ldap_bind($this->_connection, $entryDN, $password);

                    if (!$ru) {
                        $this->disconnect();
                        $user = null;
                        $this->handleMessage("{LDAPHandler} Authentication failed");
                    } else {
                        $this->handleMessage("{LDAPHandler} Authentication succeed");
                    }
                    /* AUTHENTICATION */
                }
            }
            $this->disconnect();
        }
        return $user;
    }

    /**
     * 
     * @param type $entry
     * @return \User
     * @author Lisette
     */
    private function convertToUser($entry) {
        try {
            $uid = ldap_get_values($this->_connection, $entry, "uid");
            $uid = $uid[0];
        } catch (Exception $e) {
            $this->handleErrors($e);
        }

        try {
            $name = ldap_get_values($this->_connection, $entry, "givenName");
            $name = $name[0];
        } catch (Exception $e) {
            $this->handleErrors($e);
        }

        try {
            $sn = ldap_get_values($this->_connection, $entry, "sn");
            $sn = $sn[0];
        } catch (Exception $e) {
            $this->handleErrors($e);
        }

        try {
            $mail = ldap_get_values($this->_connection, $entry, "mail");
            $mail = $mail[0];
        } catch (Exception $e) {
            $this->handleErrors($e);
        }

        $user = new User();
        $user->setUsername(trim($uid));
        $user->setPassword($uid);
        $user->setPermissions(null);
        //$user->setDisplayName("$name, $sn");        
        //$user->setEmail($mail);        

        return $user;
    }

    /**
     *
     * @param type $query
     * @return type 
     * @author Lisette
     */
    private function find($query) {
        $attrs = array("uid", "givenName", "sn", "mail");
        $sr = ldap_search($this->_connection, $this->_base_dn, $query, $attrs);
        return $sr;
    }

}

?>
